package com.fusion.lottery.auth.service.impl;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.fusion.lottery.auth.service.LoginService;
import com.fusion.lottery.entity.auth.Login;
import com.fusion.lottery.entity.auth.Role;
import com.fusion.lottery.entity.auth.Source;
import com.fusion.lottery.entity.auth.User;
import com.fusion.lottery.entity.auth.WxLogin;
import com.fusion.lottery.mapper.auth.LoginMapper;
import com.fusion.lottery.mapper.auth.UserMapper;
import com.fusion.utils.json.GlobalReturnCode;
import com.fusion.utils.json.Msg;
import com.fusion.utils.redis.RedisConstant;
import com.fusion.utils.redis.RedisUtil;
import com.fusion.utils.token.PasswordUtil;
import com.fusion.utils.token.TokenUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
 * 
 * @ClassName: LoginServiceImpl 
 * @Description: TODO
 * @author louis
 * @date 2018年3月29日 上午11:24:19
 */
@Service
public class LoginServiceImpl implements LoginService{
	
	@Value("${wx.appid}")
	private String appid;
	
	@Value("${wx.appsecret}")
	private String secret;
	
	@Autowired
	private LoginMapper loginMapper;
	
	@Autowired
	private UserMapper userMapper;
	
	@Autowired
	private RedisUtil redisUtil;
	
	@Autowired
    private RestTemplate restTemplate;
	
	@Override
	public Msg login(Login login) {
		// TODO Auto-generated method stub
		Msg msg = new Msg();
		List<User> users = null;
		//账号登录
		users = loginMapper.accountLogin(login);
		if(users != null && users.size() > 0) {
			User user = users.get(0);
			if("scope_password".equals(login.getScope())) {
				//验证密码是否正确
				if(!user.getPassword().equals(PasswordUtil.hex(login.getSecret(), user.getSalt()))) {
					msg.setCode(GlobalReturnCode.SECRET_ERROR);
					return msg;
				}
			}else if("scope_dynimic".equals(login.getScope())) {
				//验证短信验证码
				String key = RedisConstant.SMS+"1:"+login.getAppid();
				if(redisUtil.exists(key)) {
					if(!login.getSecret().equals(redisUtil.get(key, String.class))) {
						msg.setCode(GlobalReturnCode.AUTH_CODE_ERROR);
						return msg;
					}
				}else {
					msg.setCode(GlobalReturnCode.AUTH_CODE_NOT_EXIT);
					return msg;
				}
			}else {
				msg.setCode(GlobalReturnCode.AUTH_SCOPE_ERROR);
				return msg;
			}
			
			//获取用户角色
			List<Role> roles = userMapper.getRole(user.getId());
			Set<String> scopes = new HashSet<String>();
			for(Role role : roles) {
				scopes.add(role.getCode());
			}
			//获取用户权限
			List<Source> sources = userMapper.getPermission(user.getId());
			Set<String> privileges = new HashSet<String>();
			for(Source source : sources) {
				privileges.add(source.getCode());
			}
			//生成token
			String token = TokenUtil.createToken(user.getId(), scopes, privileges);
			msg.setData(token);
			
		}else {
			msg.setCode(GlobalReturnCode.USER_NOT_EXIT);
		}
		
		return msg;
	}

	@Override
	public Msg wxLogin(WxLogin wxLogin) {
		// TODO Auto-generated method stub
		Msg msg = new Msg();
		Map<String,String> data = new HashMap<String,String>();
		HttpHeaders headers = new HttpHeaders();
		//  请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
		headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
		//  封装参数，千万不要替换为Map与HashMap，否则参数无法传递
		MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
		//  也支持中文
		params.add("appid", appid);
		params.add("secret", secret );
		params.add("js_code", wxLogin.getCode());
		params.add("grant_type", "authorization_code");
		HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, headers);
		//  执行HTTP请求
		ResponseEntity<String> response = restTemplate.postForEntity("https://api.weixin.qq.com/sns/jscode2session", requestEntity , String.class );
		java.lang.reflect.Type type = new TypeToken<HashMap<String, String>>() {}.getType(); 
		Map<String,String> map = new Gson().fromJson(response.getBody(), type);
		if(map.containsKey("openid")) {
			wxLogin.setOpenId(map.get("openid"));
			data.put("session_key", map.get("session_key"));
			data.put("openid", map.get("openid"));
		}else {
			msg.setData(response);
			return msg;
		}
		
		List<User> users = null;
		User user = null;
		//账号登录
		users = loginMapper.wxLogin(wxLogin);
		if(users != null && users.size() > 0) {
			user = users.get(0);
		}else {
			user = new User();
			user.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			user.setCreateTime(System.currentTimeMillis()/1000);
			user.setStatus("0");
			user.setType("0");
			user.setOpenId(wxLogin.getOpenId());
			user.setName(wxLogin.getName());
			user.setPhoto(wxLogin.getPhoto());
			userMapper.insert(user);
		}
		
		//获取用户角色
		List<Role> roles = userMapper.getRole(user.getId());
		Set<String> scopes = new HashSet<String>();
		for(Role role : roles) {
			scopes.add(role.getCode());
		}
		//获取用户权限
		List<Source> sources = userMapper.getPermission(user.getId());
		Set<String> privileges = new HashSet<String>();
		for(Source source : sources) {
			privileges.add(source.getCode());
		}
		//生成token
		String token = TokenUtil.createToken(user.getId(), scopes, privileges);
		
		redisUtil.set(RedisConstant.USER+user.getId(), wxLogin.getOpenId());
		redisUtil.set(RedisConstant.WX+wxLogin.getOpenId(),user.getId());
		data.put("token", token);
		msg.setData(data);
		return msg;
	}

	
}
